/**
 * Copyright 2008-2009 HAN.BIFANG
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package han.bifang.business.dao;

import han.bifang.common.entity.SoaUser;
import han.bifang.common.exception.BifangErrorCode;
import han.bifang.common.exception.BifangException;
import han.bifang.common.persist.dao.DaoManager;
import han.bifang.common.persist.page.Page;
import han.bifang.common.persist.page.PagedQuery;
import han.bifang.common.persist.tx.Tx;
import han.bifang.common.persist.tx.TxManager;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @Author Kent
 */
public class UserDao {

	public static String createUser(SoaUser user) throws BifangException {
		Tx tx = null;

		try {
			tx = TxManager.start();
			String hql = "from SoaUser s where s.loginName = ?";
			List users = DaoManager.getDao().find(hql, user.getLoginName());
			if (users.size() > 0) {
				throw new BifangException(
						BifangErrorCode.LOGIN_NAME_EXIST_ERROR, "Login name '"
								+ user.getLoginName() + "' already exists");
			}
			DaoManager.getDao().save(user);
			DaoManager.getDao().flush();
			tx.commit();
			return user.getId();

		} catch (Throwable e) {
			Log logger = LogFactory.getLog(UserDao.class);
			logger.error("UserDao.createUser()", e);
			tx.rollback();
			throw new BifangException(BifangErrorCode.DB_ERROR,
					"createUser() error", e);
		} finally {
			tx.end();
		}

	}

	public static SoaUser getUserByLoginName(String name)
			throws BifangException {
		Tx tx = null;

		try {
			tx = TxManager.start();
			String hql = "from SoaUser s where s.loginName = ?";
			List users = DaoManager.getDao().find(hql, name);

			DaoManager.getDao().flush();
			tx.commit();
			return (SoaUser) users.get(0);

		} catch (Throwable e) {
			Log logger = LogFactory.getLog(UserDao.class);
			logger.error("UserDao.getUserByLoginName()", e);
			tx.rollback();
			throw new BifangException(BifangErrorCode.DB_ERROR,
					"getUserByLoginName() error", e);
		} finally {
			tx.end();
		}

	}

	public static void modifyUser(SoaUser user) throws BifangException {
		Tx tx = null;

		try {
			tx = TxManager.start();
			String hql = "from SoaUser s where s.loginName = ?";
			List users = DaoManager.getDao().find(hql, user.getLoginName());
			if (users.size() > 0) {
				SoaUser u = (SoaUser) users.get(0);
				if (!u.getId().equals(user.getId()))
					throw new BifangException(
							BifangErrorCode.LOGIN_NAME_EXIST_ERROR,
							"Login name '" + user.getLoginName()
									+ "' already exists");
			}
			DaoManager.getDao().merge(user);
			DaoManager.getDao().flush();
			tx.commit();

		} catch (Throwable e) {
			Log logger = LogFactory.getLog(UserDao.class);
			logger.error("UserDao.modifyUser()", e);
			tx.rollback();
			throw new BifangException(BifangErrorCode.DB_ERROR,
					"modifyUser() error", e);
		} finally {
			tx.end();
		}

	}

	public static SoaUser getUserById(String id) throws BifangException {
		Tx tx = null;

		try {
			tx = TxManager.start();
			SoaUser u = (SoaUser) DaoManager.getDao().get(SoaUser.class, id);
			tx.commit();

			return u;
		} catch (Throwable e) {
			Log logger = LogFactory.getLog(UserDao.class);
			logger.error("UserDao.getUserById()", e);
			tx.rollback();
			throw new BifangException(BifangErrorCode.DB_ERROR,
					"getUserById() error", e);
		} finally {
			tx.end();
		}

	}

	public static void removeUser(String id) throws BifangException {
		Tx tx = null;

		try {
			tx = TxManager.start();
			SoaUser u = (SoaUser) DaoManager.getDao().get(SoaUser.class, id);
			DaoManager.getDao().delete(u);
			tx.commit();

		} catch (Throwable e) {
			Log logger = LogFactory.getLog(UserDao.class);
			logger.error("UserDao.removeUser()", e);
			tx.rollback();
			throw new BifangException(BifangErrorCode.DB_ERROR,
					"removeUser() error", e);
		} finally {
			tx.end();
		}

	}

	public static List findUsersOfGroupByPage(String id, int page, int pageSize)
			throws BifangException {
		Tx tx = null;

		try {
			tx = TxManager.start();
			String hql = "select u  from SoaUser u, SoaUsergroupUserRel r where r.compId.usergroupId = '"
					+ id + "' and r.compId.userId = u.id";
			PagedQuery pq = new PagedQuery(hql, page, pageSize);
			Page p = pq.getPage();
			int total = p.getPaginator().getPageNumber();
			ArrayList ret = new ArrayList();
			ret.add(total);
			ret.add(p.getList());

			tx.commit();

			return ret;

		} catch (Throwable e) {
			Log logger = LogFactory.getLog(UserDao.class);
			logger.error("UserDao.findUserByGroupId()", e);
			tx.rollback();
			throw new BifangException(BifangErrorCode.DB_ERROR,
					"findUserByGroupId() error", e);
		} finally {
			tx.end();
		}

	}

	public static List findUsersNotOfGroupByPage(String id,String userName,String loginName, int page, int pageSize)
			throws BifangException {
		Tx tx = null;

		try {
			tx = TxManager.start();
			
			String hql = "from SoaUser m where m.id not in (select u.id from SoaUser u, SoaUsergroupUserRel r where r.compId.usergroupId = '"
					+ id + "' and r.compId.userId = u.id)";
			if(userName != null){
				hql += " and m.userName like '%" + userName + "'";
			}
			if(loginName != null){
				hql += " and m.loginName like '%" + loginName + "'";
			}
			PagedQuery pq = new PagedQuery(hql, page, pageSize);
			Page p = pq.getPage();
			int total = p.getPaginator().getPageNumber();
			ArrayList ret = new ArrayList();
			ret.add(total);
			ret.add(p.getList());

			tx.commit();

			return ret;

		} catch (Throwable e) {
			Log logger = LogFactory.getLog(UserDao.class);
			logger.error("UserDao.findUserByGroupId()", e);
			tx.rollback();
			throw new BifangException(BifangErrorCode.DB_ERROR,
					"findUserByGroupId() error", e);
		} finally {
			tx.end();
		}

	}

	public static List findUserByRoleId(String id) throws BifangException {
		Tx tx = null;

		try {
			tx = TxManager.start();
			String hql = "select u  from SoaUser u, SoaUserRoleRel r where r.compId.roleId = '"
					+ id + "' and r.compId.userId = u.id";
			List ret = DaoManager.getDao().find(hql, id);

			tx.commit();
			return ret;

		} catch (Throwable e) {
			Log logger = LogFactory.getLog(UserDao.class);
			logger.error("UserDao.findUserByGroupId()", e);
			tx.rollback();
			throw new BifangException(BifangErrorCode.DB_ERROR,
					"findUserByGroupId() error", e);
		} finally {
			tx.end();
		}

	}

	public static List findUsersByPage(String loginName, String userName,
			int page, int pageSize) throws BifangException {
		Tx tx = null;

		try {
			tx = TxManager.start();

			String hql = "from SoaUser u where 1 = 1";
			if (loginName != null) {
				hql = hql + " and u.loginName like '%" + loginName + "%'";
			}
			if (userName != null) {
				hql = hql + " and u.userName like '%" + userName + "%'";
			}
			PagedQuery pq = new PagedQuery(hql, page, pageSize);
			Page p = pq.getPage();
			int total = p.getPaginator().getPageNumber();
			ArrayList ret = new ArrayList();
			ret.add(total);
			ret.add(p.getList());
			tx.commit();

			return ret;

		} catch (Throwable e) {
			Log logger = LogFactory.getLog(UserDao.class);
			logger.error("UserDao.findUsersByPage()", e);
			tx.rollback();
			throw new BifangException(BifangErrorCode.DB_ERROR,
					"findUsersByPage() error", e);
		} finally {
			tx.end();
		}
	}
}
